#include "string-buffer.h"
#include <gc/gc.h>

void buffer_append_char(UChar **buffer, UChar character, size_t *buffer_size)
{
  size_t buffer_length = u_strlen(*buffer);
  size_t total_length = buffer_length + 1*sizeof(UChar) + 1;
  while(*buffer_size < total_length)
  {
    *buffer_size = *buffer_size *2;
    *buffer = GC_realloc(*buffer,*buffer_size*2);
  }
  u_strncat(*buffer,&character,1);
 
}

void buffer_append(UChar **buffer, UChar *string, size_t *buffer_size)
{
  size_t buffer_length = u_strlen(*buffer);
  size_t string_length = u_strlen(string);
  size_t total_length = buffer_length + string_length + 1;
  while(*buffer_size < total_length)
  {
    *buffer_size = *buffer_size *2;
    *buffer = GC_realloc(*buffer,*buffer_size*2);
  }
  u_strcat(*buffer,string);
}

string_buffer_t *make_string_buffer(size_t size)
{
  string_buffer_t *new_buffer = GC_malloc(sizeof(string_buffer_t));
  // Actual string storage
  new_buffer->string = GC_malloc(size*sizeof(UChar));
  // Null byte
  new_buffer->length = 1*sizeof(UChar);
  // Maximum storage available
  new_buffer->size = size;
  return new_buffer;
}

void string_buffer_append(string_buffer_t *buffer, UChar *appendix)
{
  size_t appendix_length = sizeof(UChar) * u_strlen(appendix);
  buffer->length += appendix_length;
  
  if(buffer->size < buffer->length)
  {
    do
    {
      buffer->size *= 2;
    } while(buffer->size < buffer->length);
    buffer->string = GC_realloc(buffer->string, buffer->size);
  }
  u_strcat(buffer->string, appendix);
}

void string_buffer_append_n(string_buffer_t *buffer, UChar *appendix, size_t n)
{
  size_t appendix_length = sizeof(UChar) * u_strlen(appendix);
  buffer->length += appendix_length;
  
  if(buffer->size < buffer->length)
  {
    do
    {
      buffer->size *= 2;
    } while(buffer->size < buffer->length);
    buffer->string = GC_realloc(buffer->string, buffer->size);
  }
  u_strncat(buffer->string, appendix, n);
}

void string_buffer_append_character(string_buffer_t *buffer, UChar character)
{
  size_t appendix_length = sizeof(UChar) * 1;
  buffer->length += appendix_length;

  if(buffer->size < buffer->length)
  {
    buffer->size *= 2;
    buffer->string = GC_realloc(buffer->string, buffer->size);
  }

  u_strncat(buffer->string, &character, 1);
}

UChar *string_buffer_finalize(string_buffer_t *buffer)
{
  return GC_realloc(buffer->string, buffer->length);
}

